﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CronusModel;
using Cronus.ViewModel.Data;

namespace Cronus.ViewModel
{
    /// <summary>
    /// Provides an interface to query the tasks table in the data model.
    /// </summary>
    internal class QueryTaskInformation
    {
        //*** Constants ***//
        //*** Static ***//
        //*** Member Variables ***//
        private DataModel _DataModel = null;

        //*** Properties ***//
        //*** Constructors ***//
        internal QueryTaskInformation(DataModel aDataModel)
        {
            _DataModel = aDataModel;
        }

        //*** Abstract Methods ***//
        //*** Methods ***//
        /// <summary>
        /// Returns a collection of all tasks in the data model.
        /// </summary>
        /// <returns>Enumerable collection of tasks in the data model.</returns>
        internal IEnumerable<CronusData.TasksRow> GetAllTasks()
        {
            IEnumerable<CronusData.TasksRow> allTasks = null;

            // Query the table, but don't set up any conditions on it.
            allTasks = from aTask in _DataModel.TasksTable
                       select aTask;
            return allTasks;
        }

        /// <summary>
        /// Queries the dataset for a task with the given name.  If no task contains the same name
        /// in the dataset, NULL is returend.
        /// </summary>
        /// <param name="strTaskName">Name to query on.</param>
        /// <returns>Task with the name; NULL if no tasks exists in the dataset.</returns>
        public Task GetTaskWithName(string strTaskName)
        {
            // Query for any tasks with the name passed in.
            IEnumerable<CronusData.TasksRow> allTasksWithName = from aTask in _DataModel.TasksTable
                                                                where aTask.Name == strTaskName
                                                                select aTask;
            
            // On the first task that matches, return it to the user.  If no tasks matched the query
            // the user will be returned NULL.
            Task aTaskToReturn = null;
            foreach (CronusData.TasksRow aRow in allTasksWithName)
            {
                aTaskToReturn = new Task(aRow);
                break;
            }
            return aTaskToReturn;
        }

        /// <summary>
        /// Queries the data model to determine how many hours have been logged agaist the current
        /// task.  The function counts the duration of any activity associated with the task that
        /// starts between the given start and end times (inclusive).
        /// </summary>
        /// <param name="strTaskName">Name of the task to query against.</param>
        /// <param name="aStartDate">Start period of the query.</param>
        /// <param name="anEndDate">End period of the query.</param>
        /// <returns>Total time spent logged against the task.</returns>
        internal TimeSpan GetTaskHoursInDateRange(string strTaskName, DateTime aStartDate, DateTime anEndDate)
        {
            // Local variables
            IEnumerable<CronusData.ActivitiesRow> aDateQueryResult = null;
            IEnumerable<CronusData.ActivitiesRow> aTaskNameQuery = null;

            // This is really a query to the activities table, but the information is generally
            // needed at the task level.
            QueryActivityInformation anActivityQuery = new QueryActivityInformation(_DataModel);

            // Query the Activities table for all of the activities in the given date range.
            aDateQueryResult = anActivityQuery.GetActivitiesInDateRange(aStartDate, anEndDate);

            // Perform the second query to narrow down the task by the task name
            if ((null != strTaskName) && (String.Empty != strTaskName) &&
                (null != aDateQueryResult))
            {
                aTaskNameQuery = from anActivity in aDateQueryResult
                                 where (anActivity.TasksRow.Name == strTaskName)
                                 select anActivity;
            }
            else
            {
                // No query is being performed, just use the previous query.
                aTaskNameQuery = aDateQueryResult;
            }

            // Add up the total amount of time we've spent.
            TimeSpan aTotalTime = new TimeSpan(0);
            if (null != aTaskNameQuery) // Make sure we have a query.
            {
                foreach (CronusData.ActivitiesRow anActivity in aDateQueryResult)
                {
                    aTotalTime += anActivity.Duration;
                }
            }
            return aTotalTime;
        }
    }
}
